package roubig

import (
	"context"
	"wzgames/internal/app"
	"wzgames/internal/client"
	"wzgames/internal/codec/sfs"
	"wzgames/internal/gloader"
	"wzgames/internal/gvalidator"
	"wzgames/internal/model/gamep"
	"wzgames/internal/response"
	_ "wzgames/internal/services/games/ggroubig"
	"wzgames/internal/services/mdc"
	"wzgames/internal/services/roubig"
	"wzgames/pkg/actor/actorservice"
	"wzgames/pkg/server/ws"
)

func RunServer() error {
	bootc := gloader.BootConfig()
	return app.Start(bootc,
		app.BeforeStart(func(ctx context.Context) error {
			err := gloader.CommMgr().LoadSysConfig()
			if err == nil {
				err = gloader.CommMgr().LoadSysCurrencies(true)
			}
			if err != nil {
				return err
			}
			return gloader.CommMgr().WatchCommConfig()
		}, func(ctx context.Context) error {
			err := gloader.CommMgr().InitWdb()
			if err == nil {
				err = gloader.CommMgr().InitRedis()
			}
			if err == nil {
				err = gloader.CommMgr().InitNats()
			}
			if err != nil {
				return err
			}
			err = actorservice.StartService(roubig.Actor())
			if err != nil {
				return err
			}
			response.InitRawPacketPool()
			response.InitElapsePacketPool()
			return gloader.GameMgr().LoadRouletteInst(true, mdc.InitInstManager().OnInstChange)
		}, func(ctx context.Context) error {
			err := gloader.GameMgr().InitGameInst(gamep.RouletteGrp, mdc.InitInstManager().InitInst)
			if err != nil {
				return err
			}
			return gvalidator.InitGameInstHashIds()
		}),
		app.Server(
			ws.NewWebSocketServer(bootc.Node().WsConf,
				ws.Transmitter(sfs.NewWSMessageTransmitter(sfs.NewDefaultSFSDataSerializer())),
				ws.SendCallback(response.ReleaseRawPacket),
				ws.ActorAttach(roubig.Actor()),
			),
		),
		app.AfterStart(func(ctx context.Context) error {
			gloader.GameMgr().ListenChange()
			return gloader.GameMgr().WatchRouletteInsts()
		}),
		app.AfterStop(func(ctx context.Context) error {
			roubig.Actor().OnDestroy()
			client.CloseCatClient()
			client.CloseUCClient()
			client.CloseBetTowerClient()
			mdc.InitInstManager().Destroy()
			gloader.Res().Stop()
			return nil
		}),
	)
}
